#include "messages.h"
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>

/*
 * Czyta wiadomość ResponseMsg z pliku
 */
int readResponse(int fd, ResponseMsg* msg){
    const int msgSize = sizeof(ResponseMsg);
    ResponseMsg tmpMsg;
    int size;
    if((size = read(fd, &tmpMsg, msgSize)) == -1){
        return -1;
    }
    if(size < msgSize){
        printf("Nie można odczytać pełnej wiadomosci\n");
        return -1;
    }
    msg->status = tmpMsg.status;
    msg->processId = tmpMsg.processId;
    return 0;
}

/*
 * Zapisuje wiadomość ResponseMsg do pliku
 */
int writeResonse(int fd, ResponseMsg* msg){
    const int resSize = sizeof(ResponseMsg);
    int isOk = write(fd, msg, resSize) == resSize;
    return !isOk;
}

/*
 * Odczytuje RequestMsg z pliku
 */
int readRequest(int fd, RequestMsg* msg){
    //czytamy długość wiadomości
    int size;
    if(read(fd, &size, sizeof(int)) != sizeof(int)){
        fprintf(stderr, "Nie można odczytac dlugosci wiadomości: %s\n", strerror(errno));
        return -1;
    }

    //alokujemy bufor i czytamy wiadomość
    char* buffer = (char*)malloc(size);
    if((size = read(fd, buffer, size)) == -1){
        printf("Nie można odczytać danych: %s\n", strerror(errno));
        return -1;
    }
    RequestMsg* tmpMsg = NULL;
    const int strLen = size - sizeof(RequestMsg);

    //ustawiamy nazwę kolejki fifo
    tmpMsg = (RequestMsg*)buffer;
    if(strLen){
        char* fifoName = malloc(strLen);
        memcpy(fifoName, buffer + sizeof(RequestMsg), strLen);
        fifoName[strLen - 1] = '\0';
        msg->fifoName = fifoName;
    }else{
        msg->fifoName = "";
    }

    // ustawiamy pola struktury
    msg->lockType = tmpMsg->lockType;
    msg->processId = tmpMsg->processId;
    msg->resourceId = tmpMsg->resourceId;
    msg->timeout = tmpMsg->timeout;
    msg->type = tmpMsg->type;
    //zwalniamy bufor
    free(buffer);
    return 0;
}

/*
 * Zapisuje wiadomość ResponseMsg do pliku
 */
int writeRequest(int fd, RequestMsg* msg){
    const int reqSize = sizeof(RequestMsg);
    char* bufferPointer = NULL;
    char* buffer = NULL;
    int bufferSize = 0;
    if(msg->type == REQ_OPEN){
        const int strLen = strlen(msg->fifoName) + sizeof('\0');
        bufferSize = reqSize + strLen + sizeof(int);
        bufferPointer = buffer = (char*)malloc(bufferSize);
        //zapis dlugosci bufora
        *((int*)bufferPointer) = reqSize + strLen;
        bufferPointer = bufferPointer + sizeof(int);
        //kopiowanie danych
        memcpy(bufferPointer, msg, reqSize);
        bufferPointer = bufferPointer + reqSize;
        strcpy(bufferPointer, msg->fifoName);
    }else{
        bufferSize = reqSize + sizeof(int);
        bufferPointer = buffer = (char*)malloc(bufferSize);
        //zapis dlugosci bufora
        *((int*)bufferPointer) = reqSize;
        bufferPointer = bufferPointer + sizeof(int);
        //kopiowanie danych
        memcpy(bufferPointer, msg, reqSize);
    }

    int isOk = write(fd, buffer, bufferSize) == bufferSize;
    free(buffer);
    return !isOk;
}

